package com.zmkj.cn.sys.service.impl;

import cn.hutool.json.JSONUtil;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.zmkj.cn.comm.baseenum.IndexEnum;
import com.zmkj.cn.comm.constant.RedisConstant;
import com.zmkj.cn.comm.constant.ResultCode;
import com.zmkj.cn.comm.vo.CommonResultVo;
import com.zmkj.cn.comm.vo.RestVo;
import com.zmkj.cn.comm.vo.WxAccessTokenVo;
import com.zmkj.cn.external.constant.WechatConstant;
import com.zmkj.cn.external.entity.ExternalWxUser;
import com.zmkj.cn.external.vo.input.ExternalWxUserInputVo;
import com.zmkj.cn.sys.constant.CommConstant;
import com.zmkj.cn.sys.entity.SysManager;
import com.zmkj.cn.sys.service.ISysManagerService;
import com.zmkj.cn.sys.service.IWechatService;
import com.zmkj.cn.sys.util.RedisUtil;
import com.zmkj.cn.sys.vo.input.SysLoginWechatInputVo;
import com.zmkj.cn.sys.vo.input.SysRegistInputVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 用户管理
 *
 * @author 伍绍宇
 * @date 2021/04/23
 */
@Service
@Slf4j
public class SysManagerServiceImpl implements ISysManagerService {

    @Resource
    private RedisUtil redisUtil;
    @Resource
    private RestTemplate restTemplate;
    @Resource
    private IWechatService wechatService;
    
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    
    @Value("${wx.fwh.userFnfo.url}")
    private String userInfoUrl;

    /**
     * 注册用户
     *
     * @author 伍绍宇
     * @date 2021/04/23
     */
    @Override
    public Object registUser(SysRegistInputVo sysRegistInputVo, HttpServletRequest request) {
        String accessKey = request.getHeader(CommConstant.ACCESSKEY);
        redisUtil.add(RedisConstant.USER_INFO.value, sysRegistInputVo.getUser(), accessKey);
        return CommonResultVo.success(ResultCode.SUCCESS);
    }

    /**
     * 移除用户
     *
     * @author 伍绍宇
     * @date 2021/04/23
     */
    @Override
    public Object removeUser(SysRegistInputVo sysRegistInputVo, HttpServletRequest request) {
        String accessKey = request.getHeader(CommConstant.ACCESSKEY);
        if (redisUtil.hashKey(RedisConstant.USER_INFO.value, sysRegistInputVo.getUser())) {
            String localAccessKey = redisUtil.getMap(RedisConstant.USER_INFO.value, sysRegistInputVo.getUser()).toString();
            if (localAccessKey.equals(accessKey)) {
                // 删除用户
                redisUtil.delete(RedisConstant.USER_INFO.value, sysRegistInputVo.getUser());
                return CommonResultVo.success(ResultCode.SUCCESS);
            }else {
                return CommonResultVo.failed(ResultCode.FORBIDDEN);
            }
        }
        return CommonResultVo.failed(ResultCode.WX_BIND_ERROR);
    }
    
    
    /**
     * 获取用户微信相关id
     *
     * @author 伍绍宇
     * @date 2021/04/23
     */
    @Override
    public Object readUser(SysRegistInputVo sysRegistInputVo, HttpServletRequest request) {
    	List<SysManager> sysManagers = new ArrayList<SysManager>();
    	String[] users = StringUtils.split(sysRegistInputVo.getUser(),",");
    	if(users!=null && users.length>0) {
    		for (int j = 0; j < users.length; j++) {
    			SysManager sysManager = new SysManager();
           	 	String unionId = (String) redisTemplate.opsForHash().get("user_open", users[j]);
           	 	sysManager.setMblNo(users[j]);
           	 	sysManager.setUnionId(unionId);
          		 if(StringUtils.isNotEmpty(unionId)) {
                  	 String openId = (String) redisTemplate.opsForHash().get("union_user", unionId);
                  	 sysManager.setOpenId(openId);
                     String fwhOpenId = (String) redisTemplate.opsForHash().get("union_fwh_user", unionId);
                     sysManager.setFwhOpenId(fwhOpenId);
                 }
          		log.info("phone {} unionid {} openid {} fwhOpenId {}",sysManager.getMblNo(),sysManager.getUnionId(),sysManager.getOpenId(),sysManager.getFwhOpenId());
          		sysManagers.add(sysManager);
    		}
    	}
    	 return CommonResultVo.success(sysManagers);
    }

    /**
     * 通过订阅绑定
     */
    @Override
    public void bindWithSubscribe(HttpServletRequest request, String openId) {
        // 通过微信接口获取
        String userInfo = restTemplate.getForObject(userInfoUrl, String.class, wechatService.createAccessToken(), openId);
        log.info("订阅事件,消息内容：{}",userInfo);
        if (JSONUtil.isJson(userInfo)) {
            cn.hutool.json.JSONObject wechatData = JSONUtil.parseObj(userInfo);
            // 过滤错误
            if (wechatData != null && wechatData.get(WechatConstant.ERRCODE.value) == null) {
                ExternalWxUserInputVo externalWxUser = getInfo(wechatData);
                if (!redisUtil.hashKey(RedisConstant.UNION_FWH_USER.value, externalWxUser.getUnionid())) {
                    // 保存unionid ： 服务号openid
                    redisUtil.add(RedisConstant.UNION_FWH_USER.value, externalWxUser.getUnionid(), openId);
                    // 保存服务号个人资料
                    redisUtil.add(RedisConstant.UNION_FWH_USER_DETAIL.value, externalWxUser.getUnionid(), wechatData);
                }
            }
        }
    }

    private ExternalWxUserInputVo getInfo(cn.hutool.json.JSONObject wechatData) {
        return ExternalWxUserInputVo.builder().openid(wechatData.get("openid").toString())
                .nickname(wechatData.get("nickname").toString())
                .sex((int) wechatData.get("sex"))
                .city(wechatData.get("city").toString())
                .province(wechatData.get("province").toString())
                .country(wechatData.get("country").toString())
                .headimgurl(wechatData.get("headimgurl").toString())
                .unionid(wechatData.get("unionid").toString())
                .frequency(IndexEnum.ZERO.getCode())
                .subscribeTime(new Date(System.currentTimeMillis()))
                .build();
    }

}